/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package session.TX;


import entity.PhotoEntity;



import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import javax.ejb.Stateless;
import javax.ejb.LocalBean;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

/**
 *
 * @author Shawn Chia
 */
@Stateless
@LocalBean
public class PhotoUploadSB implements PortalManagementSBRemote{

    private static final int BUFFER_SIZE = 6124;
    @PersistenceContext()
    EntityManager entityManager;

    //////////////////////////////////////////////////////////////////////////////////////////////////////////
    //Start of Photo Gallery Code
    //////////////////////////////////////////////////////////////////////////////////////////////////////////
    public boolean addAlt(Long photoID, String desc) {
        PhotoEntity photoEntity = getPhotoEntityByID(photoID);

        if (photoEntity != null) {
            photoEntity.setAlt(desc);
            return true;
        } else {
            return false;
        }
    }

    public String getPhotoAlt(Long photoID) {
        PhotoEntity photoEntity = getPhotoEntityByID(photoID);

        if (photoEntity != null) {
            if (photoEntity.getAlt() != null) {
                String results = photoEntity.getAlt();
                if (!results.isEmpty()) {
                    return results;
                } else {
                    return null;
                }
            } else {
                return null;
            }
        } else {
            return null;
        }
    }

    //get a single file url for displaying of photo
    public String getSinglePhotoUrl(Long photoID) {
        PhotoEntity photoEntity = getPhotoEntityByID(photoID);
        if (photoEntity == null) {
            return null;
        }
        /////////////////////////////////////////////////////////////////////////////////////
        String resultString = "../../" + photoEntity.getFilePath() + photoEntity.getFileName();
        /////////////////////////////////////////////////////////////////////////////////////
        return resultString;
    }

    //deleting a single photo. photo is not removed but set to isDeleted.
    //transfering the picture to the "Deleted Folder"
    public boolean deletePhoto(Long photoID) {
        PhotoEntity photoEntity = getPhotoEntityByID(photoID);

        if (photoEntity != null) {
            photoEntity.setIsDeleted(true);
            //Transfering of File to Folder Starts Here.
            String fileName = photoEntity.getFileName();
            String filePath = photoEntity.getFilePath();

            ExternalContext extContext = FacesContext.getCurrentInstance().getExternalContext();
            //Gets the dist folder path and append what is in the varaibles to it.
            String finalFilePath = extContext.getRealPath(filePath);
            String finalFileToBeTransfered = finalFilePath + "/" + fileName; //original file
            //Variables below stored the delete path. 1st variable is used for mkdir. 2nd is the full path of the file.
            String transferfolder = extContext.getRealPath("deletedFiles//" + filePath); //transfering to this folder
            String finalFileToTransferedTo = transferfolder + "/" + fileName; //full file name to transfer to
            try {
                File folders = new File(transferfolder);
                folders.mkdirs();
                File f1 = new File(finalFileToBeTransfered);
                File f2 = new File(finalFileToTransferedTo);
                InputStream in = new FileInputStream(f1);
                OutputStream out = new FileOutputStream(f2);
                byte[] buf = new byte[1024];
                int len;
                while ((len = in.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
                in.close();
                out.close();

                //Deleting old File.
                f1.delete();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return true;
        }

        return false;
    }

    //get all photo and placed the path and file name on arraylist of string
    //uploaderID and type makes the photo unique to the uploader
    //possible type : promotion,gallery,page,group,user,dishes(this is the outlet id).
    public ArrayList<String> getAllPhotoToString(String uploaderName, String type) {
        ArrayList<String> resultList = new ArrayList<String>();

        ArrayList<PhotoEntity> photoEntityCollection = new ArrayList<PhotoEntity>();
        photoEntityCollection = getPhotoEntityByNameAndType(uploaderName, type);
        if (!photoEntityCollection.isEmpty()) {
            for (Object o : photoEntityCollection) {
                PhotoEntity photoEntity = (PhotoEntity) o;
                if (photoEntity.getAlt() != null) {
                    resultList.add(photoEntity.getFilePath() + photoEntity.getFileName() + "," + photoEntity.getAlt());
                } else {
                    resultList.add(photoEntity.getFilePath() + photoEntity.getFileName() + "," + "No Alt Text");
                }
            }
            if (resultList.isEmpty()) {
                return null;
            } else {
                return resultList;
            }
        } else {
            return null;
        }
    }

    //supports getAllPhotoToString(Long uploaderID,String type)
    //gets all photo entity rows from the database that belongs to a unique user using uploaderID and type.
    //isDeleted Field is checked here
    public ArrayList<PhotoEntity> getPhotoEntityByNameAndType(String uploaderName, String type) {
        Query query = entityManager.createQuery("SELECT a FROM PhotoEntity a WHERE a.uploaderName = :uploaderName AND a.type = :type");
        query.setParameter("uploaderName", uploaderName);
        query.setParameter("type", type);

        ArrayList<PhotoEntity> photoEntityCollection = new ArrayList<PhotoEntity>();

        try {
            if (!query.getResultList().isEmpty()) {
                for (Object o : query.getResultList()) {
                    PhotoEntity photoEntity = (PhotoEntity) o;
                    if (!photoEntity.isIsDeleted()) //checks if the photo is deleted
                    {
                        photoEntityCollection.add(photoEntity);
                    }
                }
                return photoEntityCollection;
            }
        } catch (NoResultException ex) {
            ex.printStackTrace();
        }
        return photoEntityCollection;
    }

    //this method is used to construct the selection menu for manage photo. 
    //it generates an arrayList of SelectItem to be used to populate the data on the multi select portion of the form.
    public ArrayList<SelectItem> getAllPhoto(String uploaderName, String type) {
        ArrayList<PhotoEntity> photoEntityCollection = new ArrayList<PhotoEntity>();
        photoEntityCollection = getPhotoEntityByNameAndType(uploaderName, type);

        ArrayList<SelectItem> resultList = new ArrayList<SelectItem>();
        if (!photoEntityCollection.isEmpty()) {
            for (PhotoEntity photoEntity : photoEntityCollection) {
                resultList.add(new SelectItem(photoEntity.getId().toString(), photoEntity.getFileName()));
            }
            if (!resultList.isEmpty()) {
                return resultList;
            }
        }
        return null;
    }

    //get photoEntity by giving the photoID.
    public PhotoEntity getPhotoEntityByID(Long photoID) {
        Query query = entityManager.createQuery("SELECT a FROM PhotoEntity a WHERE a.id = :photoID");
        query.setParameter("photoID", photoID);

        PhotoEntity photoEntity = null;
        try {
            photoEntity = (PhotoEntity) query.getSingleResult();
            if (photoEntity == null) {
                return null;
            }
        } catch (NoResultException ex) {
            ex.printStackTrace();
        }
        return photoEntity;
    }

    //insertingPhoto.
    public boolean insertPhoto(InputStream MBInputStream, String fileName, String filePath, String uploaderName, String type) {
        PhotoEntity photoEntity = new PhotoEntity();
        String[] tempString = getFileNameAndExtension(fileName); //seperates the file name from the extension : [0] file name [1] extension
        //Integer photoNumber = getLastPhotoNumber(); //get the last row number to be appended to the file
        String finalFileName = tempString[0] +  "." + tempString[1];

        ExternalContext extContext = FacesContext.getCurrentInstance().getExternalContext();
        //Gets the dist folder path and append what is in the varaibles to it.
        String finalFilePath = extContext.getRealPath(filePath);

        String finalFileToBeWritten = finalFilePath + "/" + finalFileName;
        //String finalFilePath = filePath + "/" +categoryEntity.getDescription() +"/"+ stakeholderEntity.getName();
        //String relativePath = "/userUploads/files/"+categoryEntity.getDescription() +"/"+ stakeholderEntity.getName();
        ////////String finalFilePath = filePath + "//cat" + "//stakeholder";

        photoEntity.setDateUploaded(getDateTimeNow("yyyy.MM.dd G 'at' hh:mm:ss z"));
        photoEntity.setFileName(finalFileName);
        photoEntity.setFilePath(filePath); //stores the relative path
        photoEntity.setUploaderName(uploaderName);
        photoEntity.setType(type);
        photoEntity.setIsDeleted(false);
        entityManager.persist(photoEntity);


        try {
            File folders = new File(finalFilePath);
            folders.mkdirs();
            File photoFile = new File(finalFileToBeWritten);
            FileOutputStream fileOutputStream = new FileOutputStream(photoFile);

            byte[] buffer = new byte[BUFFER_SIZE];

            int bulk;
            InputStream inputStream = MBInputStream;
            while (true) {
                bulk = inputStream.read(buffer);
                if (bulk < 0) {
                    break;
                }
                fileOutputStream.write(buffer, 0, bulk);
                fileOutputStream.flush();
            }

            fileOutputStream.close();
            inputStream.close();

            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    //supports insertPhoto(.....)
    //To get the last photo number of the file so that a number can be appended to all files.
    public Integer getLastPhotoNumber() {
        Query query = entityManager.createQuery("SELECT a FROM PhotoEntity a");
        try {
            return query.getResultList().size();

        } catch (NoResultException ex) {
            return 0;
        }
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////
    //Supporting Methods
    //////////////////////////////////////////////////////////////////////////////////////////////////////////
    public String[] getFileNameAndExtension(String input) {
        String fileName = "";
        String extension = "";
        int mid = input.lastIndexOf(".");
        fileName = input.substring(0, mid);
        extension = input.substring(mid + 1, input.length());
        String[] resultString = new String[2];
        resultString[0] = fileName;
        resultString[1] = extension;
        return resultString;
    }

  /*  public String getCategoryNameByID(Long stakeholderName) {
        Query query = entityManager.createQuery("SELECT a FROM CategoryEntity a WHERE a.id = :categoryID");
        query.setParameter("categoryID", stakeholderName);

        CategoryEntity categoryEntity = null;
        try {
            categoryEntity = (CategoryEntity) query.getSingleResult();
            if (categoryEntity == null) {
                return null;
            }
        } catch (NoResultException ex) {
            ex.printStackTrace();
        }
        return categoryEntity.getDescription();
    }
*/
   /* public String getStakeholderNameByID(Long stakeholderID) {
        Query query = entityManager.createQuery("SELECT a FROM StakeholderEntity a WHERE a.id = :stakeholderID");
        query.setParameter("stakeholderID", stakeholderID);

        StakeholderEntity stakeholderEntity = null;
        try {
            stakeholderEntity = (StakeholderEntity) query.getSingleResult();
            if (stakeholderEntity == null) {
                return null;
            }
        } catch (NoResultException ex) {
            ex.printStackTrace();
        }
        return stakeholderEntity.getName();
    }*/
/*
    public StakeholderEntity getStakeholderEntityByID(Long stakeholderID) {
        Query query = entityManager.createQuery("SELECT a FROM StakeholderEntity a WHERE a.id = :stakeholderID");
        query.setParameter("stakeholderID", stakeholderID);

        StakeholderEntity stakeholderEntity = null;
        try {
            stakeholderEntity = (StakeholderEntity) query.getSingleResult();
            if (stakeholderEntity == null) {
                return null;
            }
        } catch (NoResultException ex) {
            ex.printStackTrace();
        }
        return stakeholderEntity;
    }
*/
    public String getDateTimeNow(String dateFormat) {
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        return sdf.format(cal.getTime());
    }
}
